package org.huamoxi.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.huamoxi.constant.SecurityConstants;
import org.huamoxi.constant.TokenConstants;

import java.util.Calendar;
import java.util.Map;

public class JwtUtils {
    // 密钥
    public static final String secret = TokenConstants.SECRET;

    public static final int expire = TokenConstants.EXPIRE; //过期时间，7天

    /**
     * 从数据声明生成令牌
     *
     * @param claims 数据声明
     * @return 令牌
     */
    public static String generateToken(String sub, Map<String, Object> claims) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, expire);

        claims.put("exp", calendar.getTime());

        return Jwts.builder()
                .setSubject(sub)
                .setClaims(claims)
                .setExpiration(calendar.getTime())
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }

    /**
     * 从令牌中获取数据声明
     *
     * @param token 令牌
     * @return 数据声明
     */
    public static Claims verifyToken(String token) {
        return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
    }

    /**
     * 校验令牌是否过期
     * @param token 要校验的令牌
     * @return true过期 false未过期
     */
    public static Boolean isExpiration(String token) {
        Claims claims = verifyToken(token);
        Long exp = getLongValue(claims, "exp");
        long currentTime = System.currentTimeMillis();
        if (exp - currentTime < 0)
            return true;
        return false;
    }

    /**
     * 根据令牌获取用户信息
     *
     * @param token 令牌
     * @return 用户ID
     */
    public static String getUserId(String token)
    {
        Claims claims = verifyToken(token);
        return getStringValue(claims, SecurityConstants.USER_KEY);
    }

    /**
     * 根据令牌获取用户信息
     *
     * @param token 令牌
     * @return 用户nickName
     */
    public static String getUserNickname(String token)
    {
        Claims claims = verifyToken(token);
        return getStringValue(claims, SecurityConstants.NICKNAME);
    }

    /**
     * 根据令牌获取用户信息
     *
     * @param token 令牌
     * @return 用户nickName
     */
    public static String getUserName(String token)
    {
        Claims claims = verifyToken(token);
        return getStringValue(claims, SecurityConstants.NAME);
    }

    /**
     * 根据身份信息获取键值
     *
     * @param claims 身份信息
     * @param key 键
     * @return 值
     */
    public static String getStringValue(Claims claims, String key)
    {
        return claims.get(key).toString();
    }

    /**
     * 根据身份信息获取键值
     *
     * @param claims 身份信息
     * @param key 键
     * @return 值
     */
    public static Long getLongValue(Claims claims, String key)
    {
        return Long.parseLong(claims.get(key).toString());
    }
}
